home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / PASCAL / FPKPAS65.ZIP / SRCRTLDO.ZIP / SOURCE / RTL / DOS / HEAP.INC < prev    next >
Encoding:
Text File  |  1996-07-23  |  7.1 KB  |  249 lines

  1. {****************************************************************************
  2.  
  3.                    Copyright (c) 1994,96 by Florian Klaempfl
  4.  
  5.  ****************************************************************************}
  6.  
  7. {****************************************************************************
  8.                functions for heap management in the data segment
  9.  ****************************************************************************}
  10.  
  11.     var
  12.        { blocks : array[1..32] of pointer; }
  13.        _memavail : longint;
  14.  
  15.     function memavail : longint;
  16.  
  17.       begin
  18.          memavail:=_memavail;
  19.       end;
  20.  
  21.     type
  22.        pfreerecord = ^tfreerecord;
  23.  
  24.        tfreerecord = record
  25.           next : pfreerecord;
  26.           size : longint;
  27.        end;
  28.  
  29.     function maxavail : longint;
  30.  
  31.       var
  32.          hp : pfreerecord;
  33.  
  34.       begin
  35.          maxavail:=heapend-heapptr;
  36.          hp:=freelist;
  37.          while assigned(hp) do
  38.            begin
  39.               if hp^.size>maxavail then
  40.                 maxavail:=hp^.size;
  41.               hp:=hp^.next;
  42.            end;
  43.       end;
  44.  
  45.     procedure getmem(var p : pointer;size : longint);[public,alias: 'GETMEM'];
  46.  
  47.  
  48.       function call_heaperror(size : longint) : integer;
  49. {$ifdef DOS}
  50.         begin
  51.            asm
  52.               pushl 12(%ebp)
  53.               movl U_SYSTEM_HEAPERROR,%eax
  54.               call (%eax)
  55.               leave
  56.               ret $8
  57.            end;
  58.         end;
  59. {$endif}
  60. {$ifdef LINUX}
  61.         begin
  62.            asm
  63.               pushl 12(%ebp)
  64.               movl U_SYSLINUX_HEAPERROR,%eax
  65.               call (%eax)
  66.               leave
  67.               ret $8
  68.            end;
  69.         end;
  70. {$endif}
  71.  
  72.       var
  73.          last,hp : pfreerecord;
  74.          nochmal : boolean;
  75.  
  76.       begin
  77.          if size=0 then
  78.            begin
  79.               p:=heapend;
  80.               exit;
  81.            end;
  82.          { Auf Vielfaches von 8 Byte umrechnen }
  83.          if (size mod 8)<>0 then
  84.            size:=size+(8-(size mod 8));
  85.          dec(_memavail,size);
  86.          repeat
  87.            nochmal:=false;
  88.            { nun ist die freelist dran: }
  89.            if assigned(freelist) then
  90.              begin
  91.                 last:=nil;
  92.                 hp:=freelist;
  93.                 while assigned(hp) do
  94.                   begin
  95.                      { erster passender Block wird genommen }
  96.                      if hp^.size>=size then
  97.                        begin
  98.                           p:=hp;
  99.                           { wird der ganze Block benötigt ? }
  100.                           if hp^.size>size then
  101.                             begin
  102.                                (hp+size)^.size:=hp^.size-size;
  103.                                (hp+size)^.next:=hp^.next;
  104.                                if assigned(last) then
  105.                                  last^.next:=hp+size
  106.                                else
  107.                                  freelist:=hp+size;
  108.                             end
  109.                           else
  110.                             begin
  111.                                if assigned(last) then
  112.                                  last^.next:=hp^.next
  113.                                else
  114.                                  freelist:=nil;
  115.                             end;
  116.                           exit;
  117.                        end;
  118.                      last:=hp;
  119.                      hp:=hp^.next;
  120.                   end;
  121.              end;
  122.            { zuletzt wird an der Heapspitze nachgeschaut, ob }
  123.            { noch Speicher frei ist                          }
  124.            if heapend-heapptr<size then
  125.              begin
  126.                 if assigned(heaperror) then
  127.                   begin
  128.                      case call_heaperror(size) of
  129.                         0 : runerror(203);
  130.                         1 : p:=nil;
  131.                         2 : nochmal:=true;
  132.                      end;
  133.                   end
  134.                 else
  135.                   runerror(203);
  136.              end
  137.            else
  138.              begin
  139.                 p:=heapptr;
  140.                 heapptr:=heapptr+size;
  141.              end;
  142.          until not nochmal;
  143.       end;
  144.  
  145.     procedure freemem(var p : pointer;size : longint);[public,alias: 'FREEMEM'];
  146.  
  147.       var
  148.          hp : pfreerecord;
  149.  
  150.       begin
  151.          if (p<heaporg) or (p>heapptr) then
  152.            begin
  153.               writeln('pointer doesn''t points to the heap');
  154.               halt;
  155.            end;
  156.          { Auf Vielfaches von 8 Byte umrechnen }
  157.          if (size mod 8)<>0 then
  158.            size:=size+(8-(size mod 8));
  159.          inc(_memavail,size);
  160.          if p+size>=heapptr then
  161.            heapptr:=p
  162.          else
  163.            begin
  164.               { size can be allways set }
  165.               pfreerecord(p)^.size:=size;
  166.  
  167.               { if there is no free list }
  168.               if not assigned(freelist) then
  169.                 begin
  170.                    { then generate one }
  171.                    freelist:=p;
  172.                    pfreerecord(p)^.next:=nil;
  173.                    p:=nil;
  174.                    { we are ready }
  175.                    exit;
  176.                 end;
  177.               { an welcher Position der freelist einfügen? }
  178.               hp:=freelist;
  179.               while assigned(hp) do
  180.                 begin
  181.                    { conneting two blocks ? }
  182.                    if hp+hp^.size=p then
  183.                       begin
  184.                          inc(hp^.size,size);
  185.                          break;
  186.                       end
  187.                    { if the end is reached, then concat }
  188.                    else if hp^.next=nil then
  189.                      begin
  190.                         hp^.next:=p;
  191.                         pfreerecord(p)^.next:=nil;
  192.                         break;
  193.                      end
  194.                    { falls der nächste Zeiger größer ist, dann }
  195.                    { Einhängen                                 }
  196.                    else if hp^.next>p then
  197.                      begin
  198.                         { vielleicht zwei Blöcke zusammenfassen ? }
  199.                         if p+size=hp^.next then
  200.                           begin
  201.                              pfreerecord(p)^.next:=hp^.next^.next;
  202.                              inc(pfreerecord(p)^.size,hp^.next^.size);
  203.                           end
  204.                         else
  205.                           begin
  206.                              pfreerecord(p)^.next:=hp^.next;
  207.                              hp^.next:=p;
  208.                           end;
  209.                         break;
  210.                      end;
  211.                    hp:=hp^.next;
  212.                 end;
  213.            end;
  214.          p:=nil;
  215.       end;
  216.  
  217.     function getheapstart : pointer;
  218.  
  219.       begin
  220.          asm
  221.             leal HEAP,%eax
  222.             leave
  223.             ret
  224.          end ['EAX'];
  225.       end;
  226.  
  227.     function getheapsize : longint;
  228.  
  229.       begin
  230.          asm
  231.             movl HEAPSIZE,%eax
  232.             leave
  233.             ret
  234.          end ['EAX'];
  235.       end;
  236.  
  237.     procedure release(var p : pointer);
  238.  
  239.       begin
  240.          heapptr:=p;
  241.          freelist:=p;
  242.       end;
  243.  
  244.     procedure mark(var p : pointer);
  245.  
  246.       begin
  247.          p:=heapptr;
  248.       end;
  249.